QrScanner.tsx ➔ QrScanner   C
last analyzed

Complexity

Conditions 7

Size

Total Lines 96
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 96
rs 6.3526
c 0
b 0
f 0
cc 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import React, { useState, useEffect } from 'react';
2
import { Text, View, StyleSheet, Button, Modal, Pressable, TextInput } from 'react-native';
3
import { BarCodeScanner } from 'expo-barcode-scanner';
4
import Icon from 'react-native-vector-icons/Octicons';
5
import scooterModel from '../../models/scooter';
6
import { showMessage, hideMessage } from "react-native-flash-message";
7
8
export default function QrScanner({navigation, cameraVisible, setCameraVisible, scooter, setModalVisible, currentCity, setCurrentScooter}) {
9
  const [hasPermission, setHasPermission] = useState(null);
10
  const [scanned, setScanned] = useState(false);
11
  const [code, setCode] = useState(null);
12
13
    useEffect(() => {
14
      const getBarCodeScannerPermissions = async () => {
15
        const { status } = await BarCodeScanner.requestPermissionsAsync();
16
        setHasPermission(status === 'granted');
17
      };
18
19
      getBarCodeScannerPermissions();
20
    }, []);
21
22
    async function handleBarCodeScanned({ type, data }) {
23
      setScanned(true);
24
25
      await startScooter(data);
26
    };
27
28
    if (hasPermission === null) {
29
      return <Text>Requesting for camera permission</Text>;
30
    }
31
    if (hasPermission === false) {
32
      return <Text>No access to camera</Text>;
33
    }
34
35
    async function startScooter(scooter): Promise<void> {
36
      // Check if QR code is a valid scooter
37
      const result = await scooterModel.checkIfValidScooter(scooter, currentCity);
38
39
      
40
      if (result) {
41
        showMessage({
42
          message: 'Scooter scanned!',
43
          type: 'success',
44
          position: 'bottom'
45
46
        });
47
48
        setCameraVisible(!cameraVisible);
49
        setModalVisible(true);
50
        setCurrentScooter(result);
51
      } else {
52
        showMessage({
53
          message: 'Not a scooter!',
54
          type: 'danger',
55
          position: 'center'
56
        })
57
      }
58
59
      
60
    }
61
62
  return (
63
    <Modal
64
        animationType="slide"
65
        transparent={true}
66
        visible={cameraVisible}
67
        onRequestClose={() => {
68
        setCameraVisible(!cameraVisible);
69
        }}
70
    >
71
        <View style={[styles.container, styles.shadowProp]}>
72
            <Pressable style={[styles.backButton, styles.shadowProp]} onPress={() => setCameraVisible(!cameraVisible)}>
73
                <Icon 
74
                    name='x' 
75
                    size={25} 
76
                    color='black'
77
                />
78
            </Pressable>
79
            
80
            <Text style={styles.title}>Scan the QR-code</Text>
81
            <TextInput
82
            placeholder="or enter code manually"
83
            style={styles.input}
84
            onChangeText={(content: string) => {
85
                setCode(content)
86
            }}
87
            onSubmitEditing={() => startScooter(code)}
88
            />
89
        <BarCodeScanner
90
            onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
91
            style={styles.viewFinder}
92
        />
93
94
        <Pressable style={[styles.cameraButton, styles.shadowProp]} onPress={() => setScanned(false)} >
95
            <Icon 
96
                name='screen-full' 
97
                size={24} 
98
                color='black'
99
            />
100
        </Pressable>
101
        </View>
102
    </Modal>
103
104
  );
105
}
106
107
const styles = StyleSheet.create({
108
    container: {
109
      width: '100%',
110
      alignItems: 'center',
111
      backgroundColor: 'white',
112
      height: '80%',
113
      top: '20%',
114
      borderTopRightRadius: 25,
115
      borderTopLeftRadius: 25
116
117
    },
118
119
    viewFinder: {
120
        flex: 1,
121
        width: '70%',
122
    },
123
124
125
    shadowProp: {
126
        elevation: 5,
127
        shadowColor: 'black'
128
    },
129
    
130
    backButton: {
131
        position: 'absolute',
132
        width: 40,
133
        height: 40, 
134
        left: 20,
135
        backgroundColor: 'white',
136
        top: 20,
137
        borderRadius: 25,
138
        borderWidth: 1,
139
        borderColor: 'gray',
140
        alignItems: 'center',
141
        justifyContent: 'center'
142
    },
143
144
    cameraButton: {
145
        width: 60,
146
        height: 60, 
147
        backgroundColor: 'white',
148
        bottom: 50,
149
        borderRadius: 50,
150
        borderWidth: 1,
151
        borderColor: 'gray',
152
        alignItems: 'center',
153
        justifyContent: 'center'
154
    },
155
156
    title: {
157
        position: 'absolute',
158
        fontWeight: 'bold',
159
        fontSize: 20,
160
        marginTop: 30
161
    },
162
163
    subTitle: {
164
      position: 'absolute',
165
      fontSize: 12,
166
      marginTop: 55,
167
      color: 'gray'
168
  },
169
170
    input: {
171
      width: '60%',
172
      marginBottom: 30,
173
      borderRadius: 10,
174
      height: 50,
175
      padding: 10,
176
      borderBottomWidth: 2,
177
      borderColor: 'gray',
178
      marginTop: 60,
179
      textAlign: 'center'
180
    }
181
})